class SCNetModel:
    def __init__(self):
        ...
    
    def forward(self, pixel, H):
        # dim = Nc， pixel: [batch*K, C, H, W]
        # Nc每个子载波可以理解为图像在某一频率分量上的特征表示, 表示信道的分辨率
        # 1+2是联合信源信道编码 Joint Source and Channel Coding
        visual_tokens = image_quantize(pixel) # [batch*K, tokens, dim]
        # 不同Nc的实验可以在这里加一个mlp层，也就是adaptor来映射不同维度 (信道编码)
        visual_tokens = mlp(visual_tokens) # [batch*K, tokens, dim] -> [batch*K, tokens, Nc]
        visual_tokens = visual_tokens.reshape(-1, Nc, tokens)      # [batch*K, Nc, tokens]
        # 每张图像切分成Nc个patch，即切分给子载波，每个子载波可以传输2*Q信号，将比特流token映射到复数信号Q
        qsymbol = qpsk(visual_tokens)              # [batch*K, Nc, 2*Q]，实际上也是一个mlp层
        
        # 先对信道进行归一化，然后进行csi语义提取，这里是得到每一个信道上的特性，每个用户在每个载波上有信道增益矩阵2Nt，每个用户的信道增益是不同的
        commu_embeds = csi_extract(H) # [batch, K, Nc, 2*Nt] -> [batch*K, Nc, 64]
        
        # beamforming（语义融合网络，预编码网络） 将 Q符号 分配到 信道上，即将信号发送到不同频域上，因为不同频域是正交的，用于抵消一些通信损失或者分配功率之类的，我在这个载波这个天线上发出来的信号是什么样的（发送端）相当于大基站发出来的信号就一个信号，不是K个
        # 重点设计
        symbol = beamforming(commu_embeds, qsymbol) # [batch, Nc, 64*K] + [batch, Nc, 2*Q*K] -> [batch, Nc, Nt, Q] DDDL
        power = (torch.sum(torch.abs(symbol)**2,[2,3])).reshape(-1, Nc, 1, 1)
        
        noise = noise * torch.sqrt(power) / math.sqrt(self.Q)
        
        z = H @ symbol # [Batch, Nc, K, Nt] * [Batch, Nc, Nt, Q] -> [Batch, Nc, K, Q] 无线信道传播
        z = z + noise
        
        # 解调网络, 将Q符号转回比特流
        visual_tokens = demodulation(z)      # [Batch, Nc, K, Q] -> [batch*K, Nc, tokens]
        
        # 信道解码网络，将Nc频率转回像素维度
        # -1+-2联合信源信道解码 Joint Source and Channel Decoding
        visual_tokens = Hdecode(visual_tokens) # [batch*K, Nc, tokens] -> [batch*K, dim, tokens]
        
        # 图像解码网络
        x_hat = image_decode(visual_tokens)             # [batch*K, tokens, dim] -> [batch*K, c, w, h]
        
        return x_hat